package com.ruoyi.order.controller;

import java.util.Date;
import java.util.List;
import java.io.IOException;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson2.JSON;
import com.alibaba.nacos.shaded.com.google.gson.Gson;
import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.order.api.RemoteOrderService;
import com.ruoyi.order.api.domain.Order;
import com.ruoyi.order.domain.OrderService;
import com.ruoyi.order.service.IOrderService;
import com.ruoyi.order.service.IOrderServiceService;
import com.ruoyi.service.api.RemoteServiceService;
import com.ruoyi.service.api.domain.CheService;
import com.ruoyi.shop.api.RemoteDrawalService;
import com.ruoyi.shop.api.RemoteShopService;
import com.ruoyi.shop.api.domain.CheDrawal;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.common.security.annotation.RequiresPermissions;
import com.ruoyi.order.domain.CheStatement;
import com.ruoyi.order.service.ICheStatementService;
import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.utils.poi.ExcelUtil;
import com.ruoyi.common.core.web.page.TableDataInfo;

import static com.ruoyi.common.core.web.domain.AjaxResult.DATA_TAG;

/**
 * 收支明细Controller
 * 
 * @author 侯稼骏
 * @date 2024-12-31
 */
@RestController
@RequestMapping("/statement")
public class CheStatementController extends BaseController
{
    @Autowired
    private ICheStatementService cheStatementService;
    @Autowired
    private RemoteShopService remoteShopService;
    @Autowired
    private RemoteDrawalService remoteDrawalService;
    @Autowired
    private RemoteServiceService remoteServiceService;
    @Autowired
    private IOrderServiceService orderServiceService;

    /**
     * 查询收支明细列表
     */
//    @RequiresPermissions("order:statement:list")
    
    @GetMapping("/list")
    public TableDataInfo list(CheStatement cheStatement)
    {
        startPage();
        List<CheStatement> list = cheStatementService.selectCheStatementList(cheStatement);
        return getDataTable(list);
    }



    /**
     * 导出收支明细列表
     */
    @RequiresPermissions("order:statement:export")
    @Log(title = "收支明细", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, CheStatement cheStatement)
    {
        List<CheStatement> list = cheStatementService.selectCheStatementList(cheStatement);
        ExcelUtil<CheStatement> util = new ExcelUtil<CheStatement>(CheStatement.class);
        util.exportExcel(response, list, "收支明细数据");
    }

    /**
     * 获取收支明细详细信息
     */
    @RequiresPermissions("order:statement:query")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return success(cheStatementService.selectCheStatementById(id));
    }

    /**
     * 新增收支明细
     */
    @RequiresPermissions("order:statement:add")
    @Log(title = "收支明细", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody CheStatement cheStatement)
    {
        return toAjax(cheStatementService.insertCheStatement(cheStatement));
    }

    /**
     * 修改收支明细
     */
    @RequiresPermissions("order:statement:edit")
    @Log(title = "收支明细", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody CheStatement cheStatement)
    {
        return toAjax(cheStatementService.updateCheStatement(cheStatement));
    }

    /**
     * 删除收支明细
     */
    @RequiresPermissions("order:statement:remove")
    @Log(title = "收支明细", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) throws Exception
    {
        return toAjax(cheStatementService.deleteCheStatementByIds(ids));
    }

    /**
     * 根据商家Id获取收支明细详细信息
     */
    @RequiresPermissions("order:statement:query")
    @GetMapping(value = "/shopId/{shopId}")
    public AjaxResult getInfoByShopId(@PathVariable("shopId") Long shopId)
    {
        return success(cheStatementService.selectByShop(shopId));
    }

    /**
     * 监听消息队列，每当订单添加时，添加收支给指定商户
     * @param message
     */
    @RabbitListener(queues = "order_queue_statement")
    public void myListener1(Message message){
        //队列中的消息体Order对象
        String jsonOrder = new String(message.getBody());
        System.out.println("消费者接收到的消息为：" + jsonOrder);
        Gson gson = new Gson();
        MessageProperties messageProperties = message.getMessageProperties();
        //队列中的消息头，messageProperties得到鉴权需要的Authorization
        String authorization = messageProperties.getHeader("Authorization");
        Order order = gson.fromJson(jsonOrder, Order.class);
        System.out.println("对象解析："+order);
        //通过订单获取对应商家的信息，为了添加收支给该商户
        AjaxResult info = remoteShopService.getInfo(order.getShopId(), authorization);
        System.out.println("商店对象："+info);
        //添加收支明细表的字段
        CheStatement cheStatement = new CheStatement();
        Date date = new Date();
        cheStatement.setType(0L);
        cheStatement.setVerificationTime(date);
        cheStatement.setOrderId(order.getId());
        cheStatement.setMoney(order.getRealPrice());
        //通过订单，得到服务项目列表，组成标题
        List<Long> longs = orderServiceService.selectOrderServiceByOrderId(order.getId());
        if (longs == null || longs.isEmpty()) {
            cheStatement.setTitle(null);
        }else {
            Long[] longArray = longs.toArray(new Long[0]);
            AjaxResult serviceInfo = remoteServiceService.getInfo(longArray, authorization);
            Object o = serviceInfo.get(DATA_TAG);
//            if(o == null){
//                return;
//            }
            List<CheService> cheServices = JSON.parseArray(JSON.toJSON(o).toString(), CheService.class);
            //服务项目组成标题，用“，”连接
            String title = cheServices.stream()
                    .filter(cheService -> cheService!= null && cheService.getName()!= null)
                    .map(CheService::getName)
                    .collect(Collectors.joining(","));
            cheStatement.setTitle(title);
        }
        //添加收支明细
        cheStatementService.insertCheStatement(cheStatement);
    }

    /**
     * 监听消息队列，每当提现添加时，添加提现明细给指定商户
     * @param message
     */
    @RabbitListener(queues = "drawal_queue")
    public void myListener2(Message message){
        //队列中的消息体Order对象
        String jsonDrawal = new String(message.getBody());
        System.out.println("消费者接收到的消息为：" + jsonDrawal);
        Gson gson = new Gson();
        MessageProperties messageProperties = message.getMessageProperties();
        //队列中的消息头，messageProperties得到鉴权需要的Authorization
        String authorization = messageProperties.getHeader("Authorization");
        CheDrawal cheDrawal = gson.fromJson(jsonDrawal, CheDrawal.class);
        System.out.println("对象解析："+cheDrawal);
        //通过订单获取对应商家的信息，为了添加收支给该商户
        AjaxResult info = remoteShopService.getInfo(cheDrawal.getShopId(), authorization);
        System.out.println("商店对象："+info);
        //添加收支明细表的字段
        CheStatement cheStatement = new CheStatement();
        Date date = new Date();
        cheStatement.setType(1L);
        cheStatement.setVerificationTime(date);
        //由于drawalId是自动给的，所以这里我们得到以下drawalId
        cheStatement.setDrawalId(cheDrawal.getDrawalId());
        cheStatement.setMoney(cheDrawal.getDrawalMoney());
        cheStatement.setTitle("提现");
        //添加收支明细
        cheStatementService.insertCheStatement(cheStatement);
    }
}
